#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/hash_policy.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
#define ps putchar(' ')
#define pe putchar('\n')
#define int long long
#define eb emplace_back
#define pi pair<int, int>
#define mk make_pair
#define fi first
#define se second
#define Ad tr[p].ad
// #define Ad t[p].ad
#define ls p << 1
#define rs p << 1 | 1
// #define ls tr[p].son[0]
// #define rs tr[p].son[1]
// #define ls t[p].son[0]
// #define rs t[p].son[1]
#define len (r - l + 1)
#define mid ((l + r) >> 1)
using namespace std;
// using namespace __gnu_pbds;
inline int read()
{
    int f = 0, ans = 0;
    char c = getchar();
    while (!isdigit(c))
        f |= c == '-', c = getchar();
    while (isdigit(c))
        ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
    return f ? -ans : ans;
}
template <typename... args>
inline void read(args &...arg) { int arr[] = {(arg = read())...}; }
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
const int N = 1e5 + 5, M = N << 2, inf = 1e18, mod = 998244353;
int n, m, _K, _S, ans, s[N], pw[N];
int mp[N], col[N], fac[N], Inv[N];
vector<int> g[N];
inline int qpow(int x, int p)
{
    int ans = 1;
    while (p)
    {
        if (p & 1)
            ans = ans * x % mod;
        x = x * x % mod, p >>= 1;
    }
    return ans;
}
inline int C(int n, int m) { return fac[n] * Inv[m] % mod * Inv[n - m] % mod; }
template <typename T>
inline int Mod(T &&x) { return x >= mod ? x -= mod : x; }
inline void B()
{
    auto get = [](int i)
    { return i * qpow(i - 1, n - 1) % mod; };
    fac[0] = 1;
    for (int i = 1; i <= m; ++i)
        fac[i] = fac[i - 1] * i % mod;
    Inv[m] = qpow(fac[m], mod - 2);
    for (int i = m; i; --i)
        Inv[i - 1] = Inv[i] * i % mod;
    for (int i = min(m, _S); i; --i)
        Mod(ans += Mod(get(i) - get(i - 1) * C(i, i - 1) % mod + mod) * C(m, i) % mod * qpow(i, _K) % mod);
    // for (int i = min(m, _S); i; --i)
    //     cerr << "CE " << i << ' ' << Mod(get(i) - get(i - 1) * C(i, i - 1) % mod + mod) * C(m, i) << endl;
}
bool dfs(int u, int fa)
{
    if (col[u] == col[fa])
        return 0;
    for (int &v : g[u])
        if (v != fa && !(dfs(v, u)))
            return 0;
    return 1;
}
// unordered_map<int, int> hashh;
void brute(int p)
{
    if (p == n + 1)
    {
        if (dfs(1, 0))
        {
            int cnt = 0;
            for (int i = 1; i <= _S; ++i)
                cnt += ++mp[col[s[i]]] == 1;
            Mod(ans += pw[cnt]);
            // ++hashh[cnt];
            for (int i = 1; i <= _S; ++i)
                --mp[col[s[i]]];
        }
        return;
    }
    for (int i = 1; i <= m; ++i)
        col[p] = i, brute(p + 1);
}
signed main()
{
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    read(n, m, _K, _S);
    for (int i = 1; i <= _S; ++i)
        read(s[i]);
    for (int i = 1; i < n; ++i)
    {
        int u = read(), v = read();
        g[u].eb(v), g[v].eb(u);
    }
    for (int i = 1; i <= m; ++i)
        pw[i] = qpow(i, _K);
    if (n <= 6 && m <= 5)
        brute(1);
    else
        B();
    write(ans);
    // for (auto &i : hashh)
    //     cerr << endl
    //          << i.first << ' ' << i.second << " I";
    // ans = 0, cerr << endl
    //               << "W ";
    // B(), cerr << ans;
    return 0;
}
